package com.gitee.wsl.android.ui.spannable.span

import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Paint.FontMetricsInt
import android.graphics.RectF
import android.text.Spanned
import android.text.style.LineHeightSpan
import android.text.style.ReplacementSpan

class TagBadgeSpan(
    private val lineHeight: Int,
    private val textColor: Int,
    private val backgroundColor: Int
) : ReplacementSpan(), LineHeightSpan {
    override fun draw(
        canvas: Canvas,
        text: CharSequence,
        start: Int,
        end: Int,
        x: Float,
        top: Int,
        y: Int,
        bottom: Int,
        paint: Paint
    ) {
        val textSize = paint.textSize
        val textLength = x + measureText(paint, text, start, end)
        val badgeHeight = textSize * 2.25f
        val textOffsetVertical = textSize * 1.45f
        val badge = RectF(x, y.toFloat(), textLength, y + badgeHeight)
        paint.color = backgroundColor
        canvas.drawRoundRect(badge, CORNER_RADIUS.toFloat(), CORNER_RADIUS.toFloat(), paint)
        paint.color = textColor
        canvas.drawText(text, start, end, x, y + textOffsetVertical, paint)
    }

    override fun getSize(
        paint: Paint,
        text: CharSequence,
        start: Int,
        end: Int,
        fm: FontMetricsInt?
    ): Int {
        return Math.round(paint.measureText(text, start, end))
    }

    private fun measureText(paint: Paint, text: CharSequence, start: Int, end: Int): Float {
        return paint.measureText(text, start, end)
    }

    override fun chooseHeight(
        text: CharSequence,
        start: Int,
        end: Int,
        spanstartv: Int,
        v: Int,
        fm: FontMetricsInt
    ) {
        val incr = Math.round(0.36f * fm.ascent) // note: ascent is negative

        // first line: add space to the top
        if ((text as Spanned).getSpanStart(this) == start) {
            fm.ascent += incr
        }

        // last line: add space to the bottom
        if (text.getSpanEnd(this) == end) {
            fm.bottom -= incr
        }
    }

    companion object {
        private const val CORNER_RADIUS = 30
    }
}